package view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

import com.thuan.hibernate.Repository;
import pojo.Privilege;
import pojo.UserAccount;
import server.Server;
import util.Utils;

public class UserManageView extends ChessOnlineView implements ActionListener, MouseListener{
	private static final long serialVersionUID = -7683061137901277552L;
	
	private JTextField txtUsername, txtName,  txtScore, txtWin, txtLose, txtSigninTime;
	private JPasswordField txtPassword, txtRePassword;
	private static JComboBox<Privilege> cbPrivilege;
	
	public UserManageView(Server mainScreen) {
		super(mainScreen);
	}
	
	@Override
	public void lockText(boolean status)
	{
		txtUsername.setEnabled(!status);
		txtPassword.setEnabled(!status);
		txtRePassword.setEnabled(!status);
		txtName.setEnabled(!status);
		txtScore.setEnabled(!status);
		txtWin.setEnabled(!status);
		txtLose.setEnabled(!status);
		txtSigninTime.setEnabled(false);
	}

	@Override
	public void doAdd(){
		super.doAdd();
		
		txtUsername.setText("");
		txtPassword.setText("");
		txtRePassword.setText("");
		txtName.setText("");
		txtScore.setText("");
		txtWin.setText("");
		txtLose.setText("");
		txtSigninTime.setText("");
	}
	
	@Override
	public void doSave(){			
		String username = txtUsername.getText();
		String password = txtPassword.getText();
		String repassword = txtRePassword.getText();
		String name = txtName.getText();
		int score = 0;
		int win = 0;
		int lose = 0;
		
		Privilege privilege = null;
		if(cbPrivilege.getSelectedItem() != null)
			privilege = (Privilege) cbPrivilege.getSelectedItem();

		if(username.equals("")) {
			JOptionPane.showMessageDialog(null, "Please enter Username.");
			txtUsername.requestFocus();
			return;
		}

		if(!Utils.validUsername(username)){
			JOptionPane.showMessageDialog(null, "Username (contains 6 - 60 characters) must contain A-Z, 0-9.");
			txtUsername.selectAll();
			txtUsername.requestFocus();
			return;
		}
		
		if(password.equals("")) {
			JOptionPane.showMessageDialog(null, "Please enter Password.");
			txtPassword.requestFocus();
			return;
		}
		
		if(!Utils.validPassword(password)){
			JOptionPane.showMessageDialog(null, "Password (contains 8 - 32 characters) must contain at least one digit and one upper character.");
			txtPassword.selectAll();
			txtPassword.requestFocus();
			return;
		}
		
		if(!password.equals(repassword)) {
			JOptionPane.showMessageDialog(null, "Password and Repeat Password do not match.");
			txtRePassword.selectAll();
			txtRePassword.requestFocus();
			return;
		}
		
		if(name.equals("")) {
			JOptionPane.showMessageDialog(null, "Please enter Name.");
			txtName.requestFocus();
			return;
		}
		
		if(txtScore.getText().equals("")) {
			JOptionPane.showMessageDialog(null, "Please enter Score.");
			txtScore.requestFocus();
			return;
		}
		
		try {
			score = Integer.parseInt(txtScore.getText());
		} catch (Exception e) {
			JOptionPane.showMessageDialog(null, "Score must have integer type.");
			txtScore.selectAll();
			txtScore.requestFocus();
			return;
		}
		
		if(score < 0){
			JOptionPane.showMessageDialog(null, "Score must be greater than or equal to 0.");
			txtScore.selectAll();
			txtScore.requestFocus();
			return;
		}
		
		if(txtWin.getText().equals("")) {
			JOptionPane.showMessageDialog(null, "Please enter Win.");
			txtWin.requestFocus();
			return;
		}
		
		try {
			win = Integer.parseInt(txtWin.getText());
		} catch (Exception e) {
			JOptionPane.showMessageDialog(null, "Win must have integer type.");
			txtWin.selectAll();
			txtWin.requestFocus();
			return;
		}
		
		if(win < 0){
			JOptionPane.showMessageDialog(null, "Win must be greater than or equal to 0.");
			txtWin.selectAll();
			txtWin.requestFocus();
			return;
		}
		
		if(txtLose.getText().equals("")) {
			JOptionPane.showMessageDialog(null, "Please enter Lose.");
			txtLose.requestFocus();
			return;
		}
		
		try {
			lose = Integer.parseInt(txtLose.getText());
		} catch (Exception e) {
			JOptionPane.showMessageDialog(null, "Lose must have integer type.");
			txtLose.selectAll();
			txtLose.requestFocus();
			return;
		}
		
		if(lose < 0){
			JOptionPane.showMessageDialog(null, "Lose must be greater than or equal to 0.");
			txtLose.selectAll();
			txtLose.requestFocus();
			return;
		}
		
		if(privilege == null) {
			JOptionPane.showMessageDialog(null, "Please choose Privilege.");
			return;
		}
		
		try {	    	
			if (btnUpdate.getText().equalsIgnoreCase("Update"))
				Repository.updateUserAccount(username, password, name, score, win, lose, privilege);
			else{
				if(Repository.findUser(username) != null){
					JOptionPane.showMessageDialog(null, "Username already exists.");
					txtUsername.selectAll();
					txtUsername.requestFocus();
					return;
				}else Repository.addUserAccount(username, password, name, score, win, lose, privilege);
			}
			
			super.doSave();

		} catch (Exception e) {
			e.printStackTrace();
		}		
	}
	
	@Override
	public void addControl()
	{
		JPanel pnInfo = new JPanel();
		pnInfo.setLayout(new BorderLayout());
		JPanel pnTitle = new JPanel();
		JLabel lblTitle = new JLabel("User Account Manage");
		lblTitle.setFont(new Font("arial", Font.BOLD, 22));
		lblTitle.setForeground(Color.BLUE);
		pnTitle.add(lblTitle);
		pnInfo.add(pnUserInfo, BorderLayout.EAST);
		pnInfo.add(pnTitle, BorderLayout.SOUTH);
		pnInfo.setBorder(new EmptyBorder(0, 0, 10, 0));
		this.add(pnInfo,BorderLayout.NORTH);

		JPanel pnDetail = new JPanel();
		pnDetail.setLayout(new BorderLayout());
		
		JPanel pnCenter = new JPanel();
		pnCenter.setLayout(new BoxLayout(pnCenter, BoxLayout.Y_AXIS));	

		Vector<String> colNames = new Vector<String>( Arrays.asList( 
				new String[]{ "Username", "Name", "Score", "Win", "Lose", "Privilege", "SigninTime"})); 
		dftMolde = new DefaultTableModel(colNames, 0){
			private static final long serialVersionUID = -2941343871925263336L;
			@Override
		    public boolean isCellEditable(int row, int column) {
		       return false;
		    }
		};
		jtable = new JTable(dftMolde);
		jtable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		JScrollPane jsp = new JScrollPane(jtable);
		jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		jsp.setPreferredSize(new Dimension(0, 200));

		jtable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {	
				if (!e.getValueIsAdjusting()) {
					int Index = jtable.getSelectedRow();
					if (Index == -1) {
						return;
					}

					String username = jtable.getValueAt(Index, 0).toString();				
					DateFormat sdf = new SimpleDateFormat(dateFormat);
					
					UserAccount useraccount = Repository.findUser(username);
					txtUsername.setText(useraccount.getUsername());
					txtPassword.setText(useraccount.getPassword());
					txtRePassword.setText(useraccount.getPassword());
					txtName.setText(useraccount.getName());
					txtScore.setText(Integer.toString(useraccount.getScore()));
					txtWin.setText(Integer.toString(useraccount.getWin()));
					txtLose.setText(Integer.toString(useraccount.getLose()));
					cbPrivilege.getModel().setSelectedItem(useraccount.getPrivilege());
					
					if(useraccount.getSigninTime() != null)
						txtSigninTime.setText(sdf.format(useraccount.getSigninTime()));
					else txtSigninTime.setText("");

					btnNew.setText("Cancel");
					btnUpdate.setText("Update");
					btnUpdate.setEnabled(true);
					txtPassword.setEnabled(true);
					txtRePassword.setEnabled(true);
					txtName.setEnabled(true);
					txtScore.setEnabled(true);
					txtWin.setEnabled(true);
					txtLose.setEnabled(true);
				}
			}
		});
		pnCenter.add(jsp);

		JPanel pnUsername = new JPanel();
		JLabel lblUsername = new JLabel("Username:");
		txtUsername = new JTextField(20);			
		pnUsername.add(lblUsername);
		pnUsername.add(txtUsername);		
		pnUsername.setBorder(new EmptyBorder(10, 0, 0, 0));
		
		JPanel pnPassword = new JPanel();
		JLabel lblPassword = new JLabel("Password:");
		txtPassword = new JPasswordField(20);			
		pnPassword.add(lblPassword);
		pnPassword.add(txtPassword);
		
		JPanel pnRePassword = new JPanel();
		JLabel lblRePassword = new JLabel("Repeat Password:      ");
		txtRePassword = new JPasswordField(20);			
		pnRePassword.add(lblRePassword);
		pnRePassword.add(txtRePassword);
		
		JPanel pnName = new JPanel();
		JLabel lblName = new JLabel("Name:");
		txtName = new JTextField(20);			
		pnName.add(lblName);
		pnName.add(txtName);
		
		JPanel pnScore = new JPanel();
		JLabel lblScore = new JLabel("Score:");
		txtScore = new JTextField(20);			
		pnScore.add(lblScore);
		pnScore.add(txtScore);
		
		JPanel pnWin = new JPanel();
		JLabel lblWin = new JLabel("Win:");
		txtWin = new JTextField(20);			
		pnWin.add(lblWin);
		pnWin.add(txtWin);
		
		JPanel pnLose = new JPanel();
		JLabel lblLose = new JLabel("Lose:");
		txtLose = new JTextField(20);			
		pnLose.add(lblLose);
		pnLose.add(txtLose);

		JPanel pnPrivilege = new JPanel();
		JLabel lblPrivilege = new JLabel("Privilege:");

		cbPrivilege = new JComboBox<Privilege>();	
		cbPrivilege.setPreferredSize(new Dimension(220, 20));	

		pnPrivilege.add(lblPrivilege);
		pnPrivilege.add(cbPrivilege);		
		
		JPanel pnSigninTime = new JPanel();
		JLabel lblSigninTime = new JLabel("Sign in Time:");
		txtSigninTime = new JTextField(20);			
		pnSigninTime.add(lblSigninTime);
		pnSigninTime.add(txtSigninTime);		

		lblUsername.setPreferredSize(lblRePassword.getPreferredSize());
		lblPassword.setPreferredSize(lblRePassword.getPreferredSize());
		lblRePassword.setPreferredSize(lblRePassword.getPreferredSize());
		lblName.setPreferredSize(lblRePassword.getPreferredSize());
		lblScore.setPreferredSize(lblRePassword.getPreferredSize());
		lblWin.setPreferredSize(lblRePassword.getPreferredSize());
		lblLose.setPreferredSize(lblRePassword.getPreferredSize());
		lblPrivilege.setPreferredSize(lblRePassword.getPreferredSize());
		lblSigninTime.setPreferredSize(lblRePassword.getPreferredSize());

		lockText(true);

		pnCenter.add(pnUsername);
		pnCenter.add(pnPassword);
		pnCenter.add(pnRePassword);
		pnCenter.add(pnName);
		pnCenter.add(pnScore);
		pnCenter.add(pnWin);
		pnCenter.add(pnLose);
		pnCenter.add(pnPrivilege);
		pnCenter.add(pnSigninTime);

		JPanel pnButton = new JPanel();
		btnNew = new JButton("New");
		btnNew.setCursor(new Cursor(Cursor.HAND_CURSOR));

		btnUpdate = new JButton("Save");
		btnUpdate.setCursor(new Cursor(Cursor.HAND_CURSOR));
		
		btnDelete = new JButton("Delete");
		btnDelete.setCursor(new Cursor(Cursor.HAND_CURSOR));

		btnUpdate.setEnabled(false);

		pnButton.add(btnNew);
		pnButton.add(btnUpdate);
		pnButton.add(btnDelete);	
		pnDetail.add(pnButton, BorderLayout.SOUTH);

		pnDetail.add(pnCenter, BorderLayout.CENTER);

		this.add(pnDetail, BorderLayout.CENTER);
		
		JPanel pnSouth = new JPanel();
		pnSouth.setPreferredSize(new Dimension(0, 10));
		this.add(pnSouth, BorderLayout.SOUTH);
		
		mMainScreen.frame.getContentPane().add(this);
	}
	
	@Override
	public void getAll()
	{
		DateFormat sdf = new SimpleDateFormat(dateFormat);
		List<UserAccount> useraccounts = Repository.listUserAccounts();
		dftMolde.setRowCount(0);
		for(UserAccount i : useraccounts){
			Vector<String> vector = new Vector<String>();
			vector.add(i.getUsername());
			vector.add(i.getName());
			vector.add(Integer.toString(i.getScore()));
			vector.add(Integer.toString(i.getWin()));
			vector.add(Integer.toString(i.getLose()));
			vector.add(i.getPrivilege().getName());
			if(i.getSigninTime() != null)
				vector.add(sdf.format(i.getSigninTime()));
			else vector.add("");
			dftMolde.addRow(vector);		
		}
	}
	
	@Override
	public void getAllDataBase()
	{		
		List<Privilege> privileges = Repository.listPrivileges();
		cbPrivilege.removeAllItems();
		
		for(Privilege i : privileges){
			cbPrivilege.addItem(i);
		}
	}
	
	@Override
	public void addEvents()
	{
		super.addEvents();
	}
	
	@Override
	public void clearText()
	{		
		txtUsername.setText("");
		txtPassword.setText("");
		txtRePassword.setText("");
		txtName.setText("");
		txtScore.setText("");
		txtWin.setText("");
		txtLose.setText("");
		txtSigninTime.setText("");
	}
	
	@Override
	public void doDelete()
	{		
		if (dftMolde.getRowCount() == 0) {
			JOptionPane.showMessageDialog(null, "Empty account");
			return;							
		}
		if (jtable.getSelectedRowCount() == 0) {
			JOptionPane.showMessageDialog(null, "Please choose account to delete");
			return;							
		}
		String username = (String) jtable.getModel().getValueAt(jtable.getSelectedRow(), 0);
		int chooseAnswer = JOptionPane.showConfirmDialog(null, "Do you really want to delete [Username: "
				+ username + "]?", "Confirm", JOptionPane.YES_NO_OPTION);
		
		if(chooseAnswer == JOptionPane.YES_OPTION){
			if(Repository.deleteUserAccount(username))
				JOptionPane.showMessageDialog(null, "Completely delete [Username: "+ username +"].");	
			getAll();			
		}
	}

	@Override
	public void mouseClicked(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
}
